﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using Microsoft.Phone.Reactive;
using System.IO;
using LunchRoller.ViewModels.Json.JiePangResponse;
using System.Device.Location;
using LunchRoller.ViewModels;
using System.Windows;

namespace LunchRoller.Repositories
{
    public class  JiePangRepository:Repository<PlaceModel>
    {

        private WebClient web;
        private System.Runtime.Serialization.Json.DataContractJsonSerializer json;
        
        

        GeoCoordinate _location;

        public GeoCoordinate Location
        {
            get { return _location; }
            set {
                _location = value;
                this.Clear();
            }
        }
        public JiePangRepository(int pageSize)
        {
            
            _pageSize = pageSize;
     
            

            json = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(ResponseBody));
            this.web = new System.Net.WebClient();
            var webObserver = Observable.FromEvent<DownloadStringCompletedEventHandler, DownloadStringCompletedEventArgs>
                      (
                           eh => (o, e) => eh(o, e),
                           eh => web.DownloadStringCompleted += eh,
                           eh => web.DownloadStringCompleted -= eh);

            webObserver.Subscribe
                   (
                       o =>
                       {

                           try
                           {

                               if (!(o.EventArgs.Error != null || o.EventArgs.Cancelled))
                               {

                                   using (var ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(o.EventArgs.Result)))
                                   {
                                       ms.Seek(0, SeekOrigin.Begin);
                                       var newo = json.ReadObject(ms) as ResponseBody;

                                       this.HasMore = newo.has_more;
                                       newo.items
                                           .Select(
                                            p =>
                                            {
                                                var pm = new PlaceModel()
                                                {
                                                    Chosen = true,
                                                    Name = p.name,
                                                    Description = p.addr



                                                };
                                                return pm;
                                            }

                                           )
                                           .ToList()

                                           .ForEach
                                           (
                                                plm => this.Add(plm)
                                           );

                                   }





                               }
                               else
                               {
                                   var showMore = MessageBox.Show("网络环境出错，请检查网络。是否要查看错误信息？", "网络检测失败", MessageBoxButton.OKCancel);
                                   if (showMore == MessageBoxResult.OK)
                                   {
                                       MessageBox.Show(o.EventArgs.Error.Message);
                                   }
                               
                               }

                           }
                           catch (Exception ex)
                           {
                               var showMore = MessageBox.Show("可能街旁的数据格式有所变化，请联系作者。需要进一步详细信息么？", "信息分析出错", MessageBoxButton.OKCancel);
                               if (showMore == MessageBoxResult.OK)
                               {
                                   MessageBox.Show(ex.Message);
                               }
                              
                           }
                           finally
                           {
                               IsInvoking = false;
                           }


                       }



                   );

   
        }
        const string JIEPANG_URL = "http://api.jiepang.com/v1/locations/search?lat={0}&lon={1}&count={2}&page={3}&source={4}";
        private Uri GetUri(GeoCoordinate location)
        {
            var uri = new Uri(string.Format(JIEPANG_URL, location.Latitude, location.Longitude, PageSize, PageCount+1, "100156"));
            return uri;
        }

        private int PageCount
        {
            get { return this.Count / this.PageSize; }
        }


        bool _hasMore=true ;
            
        public bool HasMore
        {
            get { return _hasMore; }
            private set {
                _hasMore = value;
                base.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("HasMore"));
            
            }
        }


        int _pageSize;

        public int PageSize
        {
            get
            {
                return _pageSize;
            }
            private set
            {
                _pageSize = value;
                base.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("PageSize"));

            }
        }

        bool _isInvoking;

        public bool IsInvoking
        {
            get { return _isInvoking; }
            set { _isInvoking = value;
            base.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("IsInvoking"));
            IsInvokingChanged(this, new IsInvokingChangedEventArgs {  IsInvoking=value});
            }
        }




        public event EventHandler<IsInvokingChangedEventArgs> IsInvokingChanged = (o,e) => { };

        public void GetNextPageAsync(GeoCoordinate location=null)
        {
            if (location == null) location = _location;
            _location = location;
            var uri = GetUri(_location);
            IsInvoking = true;
            web.DownloadStringAsync(uri);
            
        }
        protected override void ClearItems()
        {
            base.ClearItems();
            HasMore = true;
        }
    }

    public class IsInvokingChangedEventArgs:EventArgs
    {
        public bool IsInvoking{get;set;}
    }
}
